﻿/*
 * Copyright 2010 Pieter De Rycke
 *
 * This file is part of Frozen Bubble XNA.
 *
 * Frozen Bubble XNA is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2, as published by the Free Software Foundation.
 *
 * Frozen Bubble XNA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with Frozen Bubble XNA. If not, see 
 * <http://www.gnu.org/licenses/>.
 *
 * Artwork:
 *    Alexis Younes <73lab at free.fr>
 *      (everything but the bubbles)
 *    Amaury Amblard-Ladurantie <amaury at linuxfr.org>
 *      (the bubbles)
 *
 * Soundtrack:
 *    Matthias Le Bidan <matthias.le_bidan at caramail.com>
 *      (the three musics and all the sound effects)
 *
 * Design & Programming:
 *    Guillaume Cottenceau <guillaume.cottenceau at free.fr>
 *      (design and manage the project, whole Perl sourcecode)
 *
 * XNA and Windows Phone 7 port:
 *    Pieter De Rycke
 *
 * Websites:
 *    http://www.frozen-bubble.org/
 *    http://pieterderycke.wordpress.com/
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.IO;

namespace FrozenBubble
{
    ///// <summary>
    ///// Enum describes the screen transition state.
    ///// </summary>
    //public enum ScreenState
    //{
    //    TransitionOn,
    //    Active,
    //    TransitionOff,
    //    Hidden,
    //}

    public class GameScreen
    {
        public event EventHandler Closing;
        public event EventHandler Closed;

        public GameScreen()
        {
            Components = new List<IScreenComponent>();
            IsActive = true;
            IsSerializable = true;
        }

        #region Properties

        /// <summary>
        /// Gets the manager that this screen belongs to.
        /// </summary>
        public ScreenManager ScreenManager { get; internal set; }
     
        public FrozenGame Game { get; internal set; }
        public SpriteBatch SpriteBatch { get; internal set; }
        public IInputController Input { get; internal set; }
        public Storage Storage { get; internal set; }
        public Configuration Configuration { get; internal set; }
        public ContentCache Cache { get; internal set; }

        public bool IsActive { get; set; }
        public bool IsPopup { get; protected set; }
        public bool IsSerializable { get; protected set; }

        public IList<IScreenComponent> Components { get; private set; }

        #endregion

        #region Initialization

        /// <summary>
        /// Load graphics content for the screen.
        /// </summary>
        public virtual void LoadContent() { }


        /// <summary>
        /// Unload content for the screen.
        /// </summary>
        public virtual void UnloadContent() { }

        #endregion

        /// <summary>
        /// Allows the screen to run logic, such as updating the transition position.
        /// Unlike HandleInput, this method is called regardless of whether the screen
        /// is active, hidden, or in the middle of a transition.
        /// </summary>
        public virtual void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                      bool coveredByOtherScreen) { }

        /// <summary>
        /// Allows the active screen to handle user input.
        /// </summary>
        public virtual void HandleInput(GameTime gameTime) { }

        /// <summary>
        /// This is called when the screen should draw itself.
        /// </summary>
        public virtual void Draw(GameTime gameTime) { }

        public virtual void ExitScreen()
        {
            OnClosing(EventArgs.Empty);

            ScreenManager.RemoveScreen(this);

            OnClosed(EventArgs.Empty);
        }

        /// <summary>
        /// Tells the screen to serialize its state into the given stream.
        /// </summary>
        public virtual void Serialize(Stream stream) { }

        /// <summary>
        /// Tells the screen to deserialize its state from the given stream.
        /// </summary>
        public virtual void Deserialize(Stream stream) { }

        protected void OnClosed(EventArgs args)
        {
            if (Closed != null)
            {
                Closed(this, args);
            }
        }

        protected void OnClosing(EventArgs args)
        {
            if (Closing != null)
            {
                Closing(this, args);
            }
        }
    }
}
